package socket;

import java.io.PrintStream;
import java.net.Socket;
import java.util.Collection;
import java.util.List;
import java.util.Scanner;

import models.Jogador;
import models.sala.Sala;
import models.sala.Sistema;

public class GerenciadorDoCliente implements Runnable {
	
	private Socket clientSocket, socketRetorno;
	private Sistema sistema;
	private String codificacao;
	private Jogador jogador;
	
	public static String separador = "#";
	
	public GerenciadorDoCliente(Socket socket, Socket socketRetorno, Sistema s, String codificacao) {
		this.clientSocket = socket;
		this.socketRetorno = socketRetorno;
		this.sistema = s;
		this.codificacao = codificacao;
	}
	
	@Override
	public void run() {
		String ipDoCliente = clientSocket.getInetAddress().getHostAddress();
		PrintStream writer = null;
		Scanner reader = null;
		try{
			writer = new PrintStream(clientSocket.getOutputStream(), true, codificacao);
			reader = new Scanner(clientSocket.getInputStream(), codificacao);
			while(true){
				String inmsg = reader.nextLine(); // msg enviada pelo cliente
				System.out.println("  >MSG RECEBIDA DO CLIENTE "+ ipDoCliente +": [" + inmsg +"]");
				
				//processa msg do cliente e gera msg de resposta
				if(inmsg.equalsIgnoreCase("LOGOUT") || inmsg == null || inmsg.trim().isEmpty()){
					writer.close();
					reader.close();
					if(fecharConexao()){
						System.out.println("  Conexao com o cliente "+ ipDoCliente +" encerrada normalmente");
					}
					break;
				}
				String outmsg = processarMsg(inmsg);
				
				//envia msg ao cliente
				writer.println(outmsg);
				writer.flush();
			}
		}
		catch(Exception ex){
			System.out.println("  Conexao com cliente "+ ipDoCliente +" encerrada por problemas: " + ex.getMessage());
			ex.printStackTrace();
			fecharConexao();
		}
	}
	
	private String processarMsg(String msg){
		try{
			//String msg = new String(a.getBytes(), "UTF-16");
			//msg = limparString(msg);
			String[] tokens = msg.split(separador);
			//System.out.println("pos inicial ["+ tokens[0].indexOf("autenticar") +"] frase["+ msg +"] size["+ tokens.length +"]");// ["+ tokens[0] +"] ["+ tokens[1] +"]");// ["+ tokens[2] +"] ["+ tokens[3] +"]");
			
			
			if(tokens[0].equalsIgnoreCase("autenticar")){
				
				String nome = tokens[1];
				String senha = tokens[2];
				
				if (senha.equals("123456")) {
					jogador = new Jogador();
					jogador.email = nome;
					jogador.setGerenciador(this);
					return "OK|Logado com sucesso.";
				}
				
				return "ERRO|Login e/ou senha errada.";
			}
			else if(tokens[0].equalsIgnoreCase("salas")){
				Collection<Sala> salas = sistema.verSala();
				String str = "";
				for(Sala s : salas){
						str += s.nome + "|";
				}
				if (!str.equals("")) {
					str = str.substring(0, str.length() - 1);
				}
				str = "OK|"+ str;
				return str;
			}
			else if(tokens[0].equalsIgnoreCase("jogadores")){
				Sala s = sistema.buscarSala(tokens[1]);
				String resposta = "";
				if (s != null) {
					List<Jogador> jogadores = s.jogadores;
					
					for(Jogador j : jogadores){
						resposta += j.email + "|";
					}
					resposta = "OK|"+ resposta.substring(0, resposta.length() - 1);	
				} else {
					resposta = "ERRO|A sala nao foi encontrada."; 
				}
				
				System.out.println(resposta);
				return resposta;
			}
/*			else if(tokens[0].equalsIgnoreCase("nomejogador")){
				String nome = tokens[1];
				jogador = new Jogador();
				jogador.nome = nome;
				return "OK";
			}
*/			else if(tokens[0].equalsIgnoreCase("criarsala")){
				String nome = tokens[1];
				int qtMax = Integer.parseInt(tokens[2]);
				
				System.out.println("Sala:["+ nome +"]\tmqximo: ["+ qtMax +"]");
				
				if (sistema.criarSala(nome, qtMax, jogador)) {
					return "OK|A sala foi criada.";
				}
				
				return "ERRO|A sala nao foi criada";
			}
			else if(tokens[0].equalsIgnoreCase("entrarsala")){
				String sala = tokens[1];
				
				if (sistema.entrarSala(sala, jogador)) {
					Sala salaO = sistema.buscarSala(sala);
					List<Jogador> jogadores = salaO.jogadores;
					for(Jogador j : jogadores){
						j.notificar();
					}
					
					return "OK|"+ salaO.lider.email;
				}
				
				return "ERRO|A sala ja esta cheia.";
			}
			else if(tokens[0].equalsIgnoreCase("sairsala")){
				
				Sala sala = sistema.sairSala(jogador);
				if (sala != null) {
					return "OK|O jgador foi retirado da sala.";
				}
				
				return "ERRO|O jagador nao saiu da sala.";
			}
			
			
			return "ERRO|MENSAGEM INVALIDA";
		}
		catch(Exception ex){
			ex.printStackTrace();
			return "ERRO|"+ ex.getMessage();
		}
	}
	
	private boolean fecharConexao(){
		try{
			clientSocket.close();
			return true;
		}
		catch(Exception ex){
			ex.printStackTrace();
			return false;
		}
	}
	
	private String limparString(String msg) {
		
		String [] split = msg.split("|");
		String s = "";
		for (int i = 0; i < split.length; i++) {
			if (i%2 == 1) {
				s += split[i];
			}
		}
		return s;
	}
	
	public void notificar(){
		PrintStream writer;
		try {
			writer = new PrintStream(socketRetorno.getOutputStream(), true, codificacao);
			writer.println("Atualize");
			writer.flush();
		} catch (Exception e) {
			
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		
	}

}
